<?php

namespace plugin\cms\app\bll;

use app\bll\User;
use core\attribute\Template;
use Exception;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use support\Db;
use Throwable;
use Webman\Event\Event;

class Collect
{
    /**
     * 收藏内容
     *
     * @param integer $uid
     * @param integer $contentid
     * @param integer $cid
     * @param integer $siteid
     * @return void
     */
    public function doCollect(
        int $uid,
        int $contentid,
        int $cid,
        int $siteid
    ) {

        Db::beginTransaction();
        try {
            $bllContent = new Content();
            $contentinfo = $bllContent->find($contentid, $cid, $siteid);
            if (!$contentinfo) {
                throw new Exception('内容不存在');
            }
            if ($contentinfo['collect'] != 1) {

                throw new Exception('该文章不允许收藏');
            }

            Db::table('cms_collect')
                ->insert([
                    'uid' => $uid,
                    'contentid' => $contentid,
                    'cid' => $cid,
                    'siteid' => $siteid,
                    'createtime' => date('Y-m-d H:i:s'),
                ]);

            //设置文章收藏数
            $this->setContentCollectCount($contentid, $cid, $siteid);

            //钩子
            //钩子参数 文章内容等
            $bllContent = new Content();
            $contentinfo = $bllContent->find($contentid, $cid, $siteid);
            $bllUser = new User();
            $senderinfo = $bllUser->find($uid);
            $recipientinfo = $bllUser->find($contentinfo['uid']);
            $hookdata = [
                'senderinfo' => $senderinfo, //收藏人信息
                'recipientinfo' => $recipientinfo, //被收藏人信息
                'contentinfo' => $contentinfo
            ];
            Event::dispatch('framecoder.hook', [
                'ident' => 'cms_collect_doCollect_end',
                'data'  => [
                    'sender'              => $uid,                                                           //收藏人
                    'recipient'           => $contentinfo['uid'],                                            //被收藏人 
                    'sender_usernme'      => $senderinfo['username'],
                    'reciptient_username' => $recipientinfo ? $recipientinfo['username'] : '',
                    'contentid'           => $contentid,
                    'cid'                 => $cid,
                    'siteid'              => $siteid,
                    'contenttitle'        => $contentinfo['title'],
                    'link'                => '/app/cms/home/Index/page?cid=' . $cid . '&id=' . $contentid,
                    'detaildata'          => $hookdata,
                ]
            ]);
            Db::commit();
        } catch (Throwable $th) {
            Db::rollBack();
            throw $th;
        }
    }

    /**
     * 取消收藏
     *
     * @param integer $uid
     * @param integer $contentid
     * @param integer $cid
     * @param integer $siteid
     * @return void
     */
    public function cancelCollect(
        int $uid,
        int $contentid,
        int $cid,
        int $siteid
    ) {

        Db::beginTransaction();
        try {
            $bllContent = new Content();
            $contentinfo = $bllContent->find($contentid, $cid, $siteid);
            if (!$contentinfo) {
                throw new Exception('内容不存在');
            }
            if ($contentinfo['collect'] != 1) {

                throw new Exception('该文章不允许收藏');
            }


            Db::table('cms_collect')
                ->where('uid', '=', $uid)
                ->where('contentid', '=', $contentid)
                ->where('cid', '=', $cid)
                ->where('siteid', '=', $siteid)
                ->delete();

            //设置文章收藏数
            $this->setContentCollectCount($contentid, $cid, $siteid);

            Db::commit();
        } catch (Throwable $th) {
            Db::rollBack();
            throw $th;
        }
    }


    /**
     * 设置文章收藏数
     *
     * @param integer $contentid
     * @param integer $cid
     * @param integer $siteid
     * @return void
     */
    public function setContentCollectCount(int $contentid, int $cid, int $siteid)
    {
        //collectcount
        $collectcount = Db::table('cms_collect')
            ->where('contentid', '=', $contentid)
            ->where('cid', '=', $cid)
            ->where('siteid', '=', $siteid)
            ->count();
        $bllCategory = new Category();
        $tablename = $bllCategory->getTableName($cid, $siteid);
        Db::table($tablename)
            ->where('id', '=', $contentid)
            ->where('siteid', '=', $siteid)
            ->where('cid', '=', $cid)
            ->update([
                'collectcount' => $collectcount,
            ]);
    }




    #[Template]
    /**
     * 是否收藏过
     *
     * @param integer $uid
     * @param integer $contentid
     * @param integer $cid
     * @param integer $siteid
     * @return boolean
     */
    public function isCollect(
        int $uid,
        int $contentid,
        int $cid,
        int $siteid
    ): bool {
        return  Db::table('cms_collect')
            ->where('uid', '=', $uid)
            ->where('contentid', '=', $contentid)
            ->where('cid', '=', $cid)
            ->where('siteid', '=', $siteid)
            ->exists();
    }

    /**
     * 点赞列表
     */
    public function paginate(
        int $uid,
        int|string $mid_mtablename,
        ?int $cid = null,
        ?int $siteid = null,
        int $pagesize = 20

    ): LengthAwarePaginator {

        $tablename = $mid_mtablename;
        if (is_numeric($mid_mtablename)) {
            $bllCategory = new Category();
            $tablename = $bllCategory->getTableName($cid, $siteid);
        }


        return Db::table('cms_collect')
            ->where('cms_collect.uid', '=', $uid)
            ->when($cid !== null, function ($query) use ($cid) {
                $query->where('cms_collect.cid', '=', $cid);
            })
            ->when($siteid !== null, function ($query) use ($siteid) {
                $query->where('cms_collect.siteid', '=', $siteid);
            })
            ->rightJoin($tablename, 'cms_collect.contentid', '=', $tablename . '.id')

            ->paginate(
                $pagesize,
                [
                    $tablename . '.*'
                ]
            );
    }
}
